<?php
namespace app\push\controller;
use GatewayWorker\Lib\Gateway;
use think\console\Input;
use think\console\Output;
use think\Db;

class Events
{
    public static function onWorkerStart($businessWorker)
    {
        $output = new Output();
        $output->writeln("onWorkerStart触发了！！！！");

        // 初始化数据库连接
        Db::connect();
    }

    public static function onConnect($client_id)
    {
//        var_dump("onConnect触发了！！！！");
        // 连接时不做任何操作
        $output = new Output();
        $output->writeln("onConnect触发了！！！！");
    }

    public static function onWebSocketConnect($client_id, $data)
    {
//        var_dump("onWebSocketConnect触发了！！！！");
        // WebSocket连接时也不做操作，等客户端发送身份信息
    }

    public static function onMessage($client_id, $message)
    {



        $message_data = json_decode($message, true);
        if (!$message_data) {
            return;
        }
//        var_dump("onMessage触发了！！！！");
        switch ($message_data['type']) {
            case 'host_login':
                self::hostLogin($client_id);
                break;
            case 'player_login':
                self::playerLogin($client_id, $message_data['player_id']);
                break;
            case 'start_answer':
//                $output->writeln("start_answer触发了！！！！");
                self::startAnswer($client_id);
                break;
            case 'player_answer':
                self::playerAnswer($client_id, $message_data['player_id']);
                break;
            case 'reset':
                self::resetGame($client_id);
                break;
        }
    }

    public static function onClose($client_id)
    {
        // 查找并删除玩家连接记录
        $player = Db::name('player_connections')->where('client_id', $client_id)->find();
        if ($player) {
            Db::name('player_connections')->where('client_id', $client_id)->delete();
        }
    }

    private static function hostLogin($client_id)
    {
        $output = new Output();
        $output->writeln("绑定到主持人组触发了！！！！");
        // 绑定到主持人组
        Gateway::joinGroup($client_id, 'hosts');

        // 发送当前状态
        $status = Db::name('answer_status')->order('id desc')->find();
        if (!$status) {
            $status = [
                'status' => 0,
                'winner_id' => null,
                'round' => 1
            ];
            Db::name('answer_status')->insert($status);
        }

        Gateway::sendToClient($client_id, json_encode([
            'type' => 'status_update',
            'status' => $status['status'],
            'winner_id' => $status['winner_id'],
            'round' => $status['round']
        ]));
    }

    private static function playerLogin($client_id, $player_id)
    {
        // 记录玩家连接
        $existing = Db::name('player_connections')->where('player_id', $player_id)->find();
        if ($existing) {
            // 更新现有记录
            Db::name('player_connections')->where('player_id', $player_id)->update([
                'client_id' => $client_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        } else {
            // 插入新记录
            Db::name('player_connections')->insert([
                'player_id' => $player_id,
                'client_id' => $client_id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        // 绑定到玩家组
        Gateway::joinGroup($client_id, 'players');

        // 发送当前状态
        $status = Db::name('answer_status')->order('id desc')->find();
        Gateway::sendToClient($client_id, json_encode([
            'type' => 'status_update',
            'status' => $status['status'],
            'winner_id' => $status['winner_id'],
            'round' => $status['round'],
            'player_id' => $player_id
        ]));
    }

    private static function startAnswer($client_id)
    {
        $output = new Output();
        $output->writeln("检查是否是主持人触发了！！！！");
        // 检查是否是主持人
//        if (!self::isUidInGroup($client_id, 'hosts')) {
//            return;
//        }


        // 使用数据库事务确保原子性
        Db::startTrans();
        try {
            $current_status = Db::name('answer_status')->order('id desc')->find();

            // 只有在未开始状态下才能开始
            if ($current_status['status'] != 0) {
                Db::rollback();
                return;
            }

            // 更新状态为抢答中
            Db::name('answer_status')->where('id', $current_status['id'])->update([
                'status' => 1,
                'winner_id' => null,
                'updated_at' => date('Y-m-d H:i:s')
            ]);

            Db::commit();

            // 广播给所有客户端
            Gateway::sendToGroup('players', json_encode([
                'type' => 'game_started'
            ]));

            Gateway::sendToGroup('hosts', json_encode([
                'type' => 'game_started'
            ]));

        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    private static function playerAnswer($client_id, $player_id)
    {
        // 使用数据库事务和行锁确保只有一个获胜者
        Db::startTrans();
        try {
            // 锁定当前状态记录
            $current_status = Db::name('answer_status')->lock(true)->order('id desc')->find();

            // 只有在抢答中且没有获胜者的情况下才能抢答
            if ($current_status['status'] != 1 || $current_status['winner_id'] !== null) {
                Db::rollback();
                return;
            }

            // 设置获胜者
            Db::name('answer_status')->where('id', $current_status['id'])->update([
                'status' => 2,
                'winner_id' => $player_id,
                'updated_at' => date('Y-m-d H:i:s')
            ]);

            Db::commit();

            // 广播结果
            Gateway::sendToGroup('players', json_encode([
                'type' => 'game_result',
                'winner_id' => $player_id
            ]));

            Gateway::sendToGroup('hosts', json_encode([
                'type' => 'game_result',
                'winner_id' => $player_id
            ]));

        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    /**
     * 判断指定UID是否在指定群组中
     * @param mixed $uid 要判断的用户ID
     * @param mixed $group 要检查的群组ID
     * @return bool 在群组中返回true，否则返回false
     */
   public static function  isUidInGroup($uid, $group) {
        // 获取该群组中所有在线的UID列表
        $uidsInGroup = Gateway::getUidListByGroup($group);
        $output = new Output();
//        $output->writeln("检查是否在群组中触发了！！！！".$uidsInGroup);
        // 判断目标UID是否在该列表中
        return in_array($uid, $uidsInGroup);
    }

    private static function resetGame($client_id)
    {
        // 检查是否是主持人
//        if (!self::isUidInGroup($client_id, 'hosts')) {
//            return;
//        }

        // 使用数据库事务确保一致性
        Db::startTrans();
        try {
            $current_status = Db::name('answer_status')->lock(true)->order('id desc')->find();

            if (!$current_status) {
                // 如果没有状态记录，创建一条新的
                $new_status = [
                    'status' => 0,
                    'winner_id' => null,
                    'round' => 1,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ];
                Db::name('answer_status')->insert($new_status);
            } else {
                // 更新现有状态
                Db::name('answer_status')->where('id', $current_status['id'])->update([
                    'status' => 0,
                    'winner_id' => null,
                    'round' => $current_status['round'] + 1,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
            }

            Db::commit();

            // 广播重置消息
            Gateway::sendToGroup('players', json_encode([
                'type' => 'game_reset',
                'round' => $current_status ? $current_status['round'] + 1 : 1
            ]));

            Gateway::sendToGroup('hosts', json_encode([
                'type' => 'game_reset',
                'round' => $current_status ? $current_status['round'] + 1 : 1
            ]));

        } catch (\Exception $e) {
            Db::rollback();
            // 记录错误日志
            error_log("Reset game failed: " . $e->getMessage());
        }
    }
}